/*=============================================================================

  SONY CAM HAL MODULE

  FILE: hw_sony_cam.c
  
  DESCRIPTION

    SONY CAM HAL Module

  Copyright (c) DaeSung Engineering Inc. All rights reserved.

=============================================================================*/
/*=============================================================================

  EDIT HISTORY

  ---------  -------  -------------------------------------------------------
    when        who         what, where, why
  ---------  -------  -------------------------------------------------------
   13/10/14   jyko        Initial version

=============================================================================*/

#include "hw_sony_cam_mod.h"
#include <stdio.h>
#include <string.h>

/*=============================================================================
  CONSTANT DEFINITIONS
=============================================================================*/
/*=============================================================================
  DEVICE SYCHRONIZATION
=============================================================================*/
static boolean SYNCex(cam_s *cam, CAM_CFGEX_s *s);
static boolean GETex(cam_s *cam, CAM_CFGEX_s *s);

/*=============================================================================
  INTERNAL COMMAND FUNCION DEFINITION
=============================================================================*/
//---------------------------------------------------------
// VERSION
//--------------------------------------------------------- 
static boolean VERget(cam_s *cam);

//---------------------------------------------------------
// GAIN CONTROL
//---------------------------------------------------------
static boolean GAINset(mcxt dev, int32 gainTbl/*0~18*/);
static boolean GAINget(mcxt dev, int32 *gainTbl);

//---------------------------------------------------------
// GAIN FINE-TUNES CONTROL
//---------------------------------------------------------
static boolean GAINFset(mcxt dev, int32 gainfTbl/*0~522*/);
static boolean GAINFget(mcxt dev, int32 *gainfTbl);

//---------------------------------------------------------
// PEDESTAL SETTING
//---------------------------------------------------------
static boolean PEDset(mcxt dev, int32 pedTbl/*0~255*/);
static boolean PEDget(mcxt dev, int32 *pedTbl);

//---------------------------------------------------------
// SHUTTER SPEED CONTROL
//---------------------------------------------------------
//	0 : OFF			5 : 1/250 s		10 : 1/10000s
//	1 : 1/15 s		6 : 1/500 s		11 : 1/7.5s
//	2 : 1/30 s		7 : 1/1000 s		12 : 1/2s
//	3 : 1/100 s		8 : 1/2000 s		13 : 1s
//	4 : 1/120 s		9 : 1/5000 s
static boolean SHTset(mcxt dev, int32 shtTbl/*0~13*/);
static boolean SHTget(mcxt dev, int32 *shtTbl);

//---------------------------------------------------------
// TRIGGER MODE SETTING
//---------------------------------------------------------
//	0 : OFF			
//	1 : external trigger edge detected	
//	2 : external trigger pulse width detected
static boolean TRGMset(mcxt dev, int32 trgTbl/*0~2*/);
static boolean TRGMget(mcxt dev, int32 *trgTbl);

//---------------------------------------------------------
// EXTERNAL TRIGGER POLARITY SETTING
//---------------------------------------------------------
//	0 : Negative
//	1 : Positive
static boolean TRGPset(mcxt dev, int32 trgpTbl/*0~1*/);
static boolean TRGPget(mcxt dev, int32 *trgpTbl);

//---------------------------------------------------------
// WHITE BALANCE MODE SETTING
//---------------------------------------------------------
//	0 : 3200K preset			2 : 6500K preset
//	1 : 5600K preset			3 : WB manual setting
//	4 : One Push AWB
static boolean WBset(mcxt dev, int32 wbTbl/*0~4*/);
static boolean WBget(mcxt dev, int32 *wbTbl);

//---------------------------------------------------------
// MANUAL R GAIN SETTING (white balance mode 3 only)
//---------------------------------------------------------
static boolean RGAINset(mcxt dev, int32 rgTbl/*0~0xFF*/);
static boolean RGAINget(mcxt dev, int32 *rgTbl);

//---------------------------------------------------------
// MANUAL B GAIN SETTING (white balance mode 3 only)
//---------------------------------------------------------
static boolean BGAINset(mcxt dev, int32 bgTbl/*0~0xFF*/);
static boolean BGAINget(mcxt dev, int32 *bgTbl);

//---------------------------------------------------------
// AWB DETECTION RANGE DISPLAY
//---------------------------------------------------------
static boolean AWBset(mcxt dev, int32 awbTbl/*0~1*/);
static boolean AWBget(mcxt dev, int32 *awbTbl);

//---------------------------------------------------------
// SHARPNESS SETTING
//---------------------------------------------------------
static boolean SHPset(mcxt dev, int32 shpTbl/*0~7*/);
static boolean SHPget(mcxt dev, int32 *shpTbl);

//---------------------------------------------------------
// DTL MODE SETTING (When set to OFF, automatically set "SHARP 0" & "DTL-SCL 0 0")
//---------------------------------------------------------
static boolean DTLset(mcxt dev, int32 dtlTbl/*0~1*/);
static boolean DTLget(mcxt dev, int32 *dtlTbl);

//---------------------------------------------------------
// GAMMA TABLE SETTING
//---------------------------------------------------------
//	0 : OFF			2 : Reverse
//	1 : ON			3 : Binarization
static boolean GAMset(mcxt dev, int32 gamTbl/*0~3*/);
static boolean GAMget(mcxt dev, int32 *gamTbl);

//---------------------------------------------------------
// GAMMA BINARIZATION THRESHOLD SETTING (gamma table 3 only)
//---------------------------------------------------------
static boolean GBINset(mcxt dev, int32 gbinTbl/*0~1024*/);
static boolean GBINget(mcxt dev, int32 *gbinTbl);

//---------------------------------------------------------
// BINNING MODE SETTING (for XCL_U1000 only)
//---------------------------------------------------------
//	0 : OFF			1 : Vertical Binning
static boolean BINNset(mcxt dev, int32 binnTbl/*0~1*/);
static boolean BINNget(mcxt dev, int32 *binnTbl);

//---------------------------------------------------------
// EXTERNAL TRIGGER SIGNAL INPUT SELECTION
//---------------------------------------------------------
//	0 : Camera Link		1 : DC
static boolean EXTset(mcxt dev, int32 extTbl/*0~1*/);
static boolean EXTget(mcxt dev, int32 *extTbl);

//---------------------------------------------------------
// COLOR BAR OUTPUT SETTING (for XCL-U1000C only)
//---------------------------------------------------------
//	0 : OFF			1 : ON
static boolean COLBset(mcxt dev, int32 colTbl/*0~1*/);
static boolean COLBget(mcxt dev, int32 *colTbl);

//---------------------------------------------------------
// GRAY SCALE OUPUT SETTING (for XCL-U1000 only)
//---------------------------------------------------------
//	0 : OFF			1 : ON
static boolean GRYset(mcxt dev, int32 gryTbl/*0~1*/);
static boolean GRYget(mcxt dev, int32 *gryTbl);

//---------------------------------------------------------
// SERIAL COMMUNICATION SPEED SETTING
//---------------------------------------------------------
//	0 : 4800 [bps]			2 : 19200 [bps]
//	1 : 9600 [bps]			3 : 38400 [bps]
//	4 : 57600 [ bps]
static boolean BRTset(mcxt dev, int32 brtTbl/*0~4*/);
static boolean BRTget(mcxt dev, int32 *brtTbl);

//---------------------------------------------------------
// PARTIAL SCAN SETTING
//---------------------------------------------------------
//	0 : OFF			1 : ON
static boolean PARset(cam_s *cam, int32 mod/*0~1*/, int32 st/*0~15*/, int32 end/*1~16*/);
static boolean PARget(cam_s *cam, int32 *mod, int32 *st, int32 *end);

//---------------------------------------------------------
// COLOR MATRIX SETTING (for XCL-U1000C only)
//---------------------------------------------------------
//	0 : OFF			2 : Data setting
//	1 : ON
static boolean COLMset(cam_s *cam, int32 mod/*0~2*/, int32 ele/*0~8*/, int32 val/*0~0x3FF*/);
static boolean COLMget(cam_s *cam, int32 *mod, int32 *ele, int32 *val);

//---------------------------------------------------------
// EDGE ENHANCEMENT FILTER COEFFICIENT SETTING
//---------------------------------------------------------
static boolean DTLCset(cam_s *cam, int32 k0, int32 k1, int32 k2);
static boolean DTLCget(cam_s *cam, int32 *k0, int32 *k1, int32 *k2);

//---------------------------------------------------------
// EDGE ENHANCEMENT CORING THRESHOLD SETTING
//---------------------------------------------------------
static boolean DTLTset(cam_s *cam, int32 nt, int32 pt);
static boolean DTLTget(cam_s *cam, int32 *nt, int32 *pt);

//---------------------------------------------------------
// EDGE ENHANCEMENT DATA SCALE SETTING
//---------------------------------------------------------
static boolean DTLSset(cam_s *cam, int32 nt, int32 pt);
static boolean DTLSget(cam_s *cam, int32 *nt, int32 *pt);

//---------------------------------------------------------
// EDGE ENHANCEMENT DATA LEVEL SETTING
//---------------------------------------------------------
static boolean DTLLset(cam_s *cam, int32 low, int32 upp);
static boolean DTLLget(cam_s *cam, int32 *low, int32 *upp);

//---------------------------------------------------------
// RETURN TO THE FACTORY DEFAULT 
//---------------------------------------------------------
static boolean INITset(cam_s *cam);

//---------------------------------------------------------
// SETTING SAVE
//---------------------------------------------------------
static boolean SAVset(cam_s *cam);

//---------------------------------------------------------
// SETTING READ
//---------------------------------------------------------
static boolean LOADset(cam_s *cam);


/*=============================================================================
  BASIC COMM.
=============================================================================*/
static boolean cam_MODEset(cam_s *cam, char *str);

static boolean cam_INT1set(cam_s *cam, char *str, int32 val, int32 min_val, int32 max_val, int32 digit);
static boolean cam_INT1get(cam_s *cam, char *str, int32 *val);

/*=============================================================================
  EXTERNALIZED FUNCION DEFINITION
=============================================================================*/
boolean cam_GetVersion(char *pszVer, int32 strLen)
{
	static char	szTmp[64];

	if(!pszVer)
	{
		return	FALSE;
	}
#ifdef _ODEBUG_
	sprintf(szTmp, "sony_camD.%s (%s)", "V03.001", __DATE__);
#else
	sprintf(szTmp, "sony_cam.%s (%s)", "V03.001", __DATE__);
#endif
	if(strLen > (int32)strlen(szTmp))
	{
		strcpy(pszVer, szTmp);
		return	TRUE;
	}

	return	FALSE;
}

boolean cam_GetModuleInfo(dword *pInfo)
{
	if(!pInfo)
		return	FALSE;

	*pInfo = 0xFFFFFFFF;

	return	TRUE;
}

// Initialization & Termination
mcxt cam_Alloc(ObjClient_s *c)
{
	cam_s			*cam;

	cam = (cam_s*)memCalloc(sizeof(*cam));
	CAMERR_CLEAR(cam);

	if(c == NULL)
		return	FALSE;

	if(cam == NULL)
		return	FALSE;

	cam->cli = (ObjClient_s*)memCalloc(sizeof(*c));
	memCopy(cam->cli, c, sizeof(*c));

	return	(mcxt)cam;
}

void cam_Free(mcxt dev)
{
	cam_s			*cam = CAMMOD(dev);

	if(cam == NULL)
	{
		return;
	}
	cam_Terminate(cam);
	memFree(cam);
}

boolean cam_EmulMode(mcxt dev, boolean enable)
{
	cam_s			*cam = CAMMOD(dev);

	if(cam == NULL)
	{
		return	FALSE;
	}

	cam->emul = enable;
	
	return	TRUE;
}


//-------------------------------------------------------------------
// INITIALIZATION & TERMINATION
//-------------------------------------------------------------------
boolean cam_Initialize(mcxt dev, byte comPort, byte baudRate, int32 waitTime)
{
	cam_s			*cam = CAMMOD(dev); 
	dword			baud_rate;
	ObjClient_s		c;
	RS232Setup_s		s;

	if(cam == NULL)
		return	FALSE;

	// Select baud rate
	// It's depend on the data sampling rate & items.
	switch(baudRate)
	{
	case CAM_4800_BRATE: baud_rate = CBR_4800; break;
	case CAM_9600_BRATE: baud_rate = CBR_9600; break;
	case CAM_19200_BRATE: baud_rate = CBR_19200; break;
	case CAM_38400_BRATE: baud_rate = CBR_38400; break;
	case CAM_57600_BRATE: baud_rate = CBR_57600; break;
	default: return	FALSE;
	}

	if(cam->com)
	{
		cam_Terminate(dev);
	}
	if(ISEMUL(cam))
	{
		return	cam_InitializeEMUL(dev, comPort, baudRate, waitTime);
	}
	
	// Initialize the RS232/422
	c.pUserCxt = cam;
	c.EventCbf = scom_event_cb;
	cam->com = RS232_Alloc(&c);

	s.byPort = comPort;
	s.dwBaud = baud_rate;
	s.byData = 8; // 8 bit
	s.byParity = 0; // None
	s.byStop = 0; // 1 bit    //   08-10-07
	s.dwXout = 0;
	s.dwXin = 0; 

	if(RS232_Setup(cam->com, &s) == FALSE)
	{
		DBGPRINT("232 SETUP-FAIL");
		
		CAMERR_SET(cam, CAM_COMM_ERR_EC);
		RS232_Free(cam->com);
		cam->com = NULL;
		return	FALSE;
	}
	if(RS232_Connect(cam->com) == FALSE)
	{
		int32	j;
		boolean	done = FALSE;

		for(j=0; j<20; j++)
		{
			if(j<10)
			{
				Task_Delay(500);
				Task_Switch();
			}
			else
			{
				Task_Delay(100);
				Task_Switch();
			}
			if(RS232_Connect(cam->com) == TRUE)
			{
				done = TRUE;
				break;
			}
			DBGPRINT("CAM-TRY = %d\n", (j+1));
		}
		if(done == FALSE)
		{
			CAMERR_SET(cam, CAM_COMM_ERR_EC);
			RS232_Free(cam->com);
			cam->com = NULL;
			return	FALSE;
		}
	}
	cam->com_port = comPort;
	cam->baud_rate = baudRate;

	// Buffer allocation
	cam->tx = tx_alloc(TX_LEN);
	cam->rx = rx_alloc(RX_LEN);

	// Sync. Allocation
	cam->sync = Sync_Alloc();
	cam->wait_time = waitTime;
	Sync_Set(cam->sync, TRUE);
	
	CAMERR_CLEAR(cam);

	return	TRUE;
}

boolean cam_Terminate(mcxt dev)
{
	cam_s			*cam = CAMMOD(dev);

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		return	TRUE;
	}
	//DAQstop(cam);

	if(ISEMUL(cam))
	{
		return	cam_TerminateEMUL(dev);
	}
	
	// Send somthing to finish fast.
	//......
	RS232_Disconnect(cam->com);
	RS232_Free(cam->com);
	cam->com = NULL;

	// Sync Free
	if(cam->sync)
	{
		Sync_Free(cam->sync);
		cam->sync = NULL;
	}

	tx_free(cam->tx);
	cam->tx = NULL;
	
	rx_free(cam->rx);
	cam->rx = NULL;

	CAMERR_CLEAR(cam);

	return	TRUE;
}

boolean cam_WaitTimeSet(mcxt dev, int32 waitTime /*msec*/)
{
	cam_s			*cam = CAMMOD(dev); 

	if(cam == NULL)
		return	FALSE;
	
	cam->wait_time = waitTime;

	return	TRUE;
}

boolean cam_WaitTimeGet(mcxt dev, int32 *waitTime/*msec*/)
{
	cam_s			*cam = CAMMOD(dev); 

	if(cam == NULL)
		return	FALSE;
	
	*waitTime = cam->wait_time;

	return	TRUE;
}


//---------------------------------------------------------
// VERSION
//---------------------------------------------------------
charptr cam_DevVersion(mcxt dev)
{
	cam_s			*cam = CAMMOD(dev); 

	if(cam == NULL)
		return	NULL;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	NULL;
	}
	
	return	&cam->ver[0];
}

//---------------------------------------------------------
// CONFIGURATION
//---------------------------------------------------------
// ADVANCED
boolean cam_CFGEXset(mcxt dev, CAM_CFGEX_s *cfg)
{
	cam_s		*cam = CAMMOD(dev);

	if(cfg == NULL)
	{
		CAMERR_SET(cam, CAM_PARAM_EC); 
		return	FALSE;
	}
	if(ISEMUL(dev))
	{
		return	cam_CFGEXsetEMUL(dev, cfg);
	}
	
	return	SYNCex(cam, cfg);
}

boolean cam_CFGEXget(mcxt dev, CAM_CFGEX_s *cfg)
{
	cam_s		*cam = CAMMOD(dev);

	if(cam == NULL)
		return	FALSE;

	//memCopy(cfg, &cam->cfg_ex, sizeof(*cfg));

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	
	return	GETex(cam, cfg);
}

// SAVE TO DEVICE
boolean cam_CFGSave(mcxt dev)
{
	if(ISEMUL(dev))
	{
		return	cam_CFGSaveEMUL(dev);
	}
	
	return	SAVset(CAMMOD(dev));
}

//---------------------------------------------------------
// SETUP
//---------------------------------------------------------
boolean cam_GAINset(mcxt dev, int32 gain/*0~18*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_GAINsetEMUL(dev, gain);
	}
	
	if(GAINset(cam, gain) == TRUE)
	{
		cam->cfg_ex.gain = gain;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_GAINget(mcxt dev, int32 *gain)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*gain = cam->cfg_ex.gain;
	
	return	TRUE;
}

boolean cam_SHUTTERset(mcxt dev, int32 sht/*0~13*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_SHUTTERsetEMUL(dev, sht);
	}
	
	if(SHTset(cam, sht) == TRUE)
	{
		cam->cfg_ex.exp_time = sht;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_SHUTTERget(mcxt dev, int32 *sht)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*sht = cam->cfg_ex.exp_time;
	
	return	TRUE;
}

boolean cam_WBset(mcxt dev, int32 mod/*0~4*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_WBsetEMUL(dev, mod);
	}
	
	if(WBset(cam, mod) == TRUE)
	{
		cam->cfg_ex.wbmod = (byte)mod;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_WBget(mcxt dev, int32 *mod)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*mod = (int32)cam->cfg_ex.wbmod;
	
	return	TRUE;
}

boolean cam_RGAINset(mcxt dev, int32 rgain)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_RGAINsetEMUL(dev, rgain);
	}
	
	if(RGAINset(cam, rgain) == TRUE)
	{
		cam->cfg_ex.rgain = rgain;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_RGAINget(mcxt dev, int32 *rgain)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*rgain = cam->cfg_ex.rgain;
	
	return	TRUE;
}

boolean cam_BGAINset(mcxt dev, int32 bgain)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_BGAINsetEMUL(dev, bgain);
	}
	
	if(BGAINset(cam, bgain) == TRUE)
	{
		cam->cfg_ex.bgain = bgain;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_BGAINget(mcxt dev, int32 *bgain)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*bgain = cam->cfg_ex.bgain;
	
	return	TRUE;
}

boolean cam_WBWset(mcxt dev, int32 enable/*0~1*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_WBWsetEMUL(dev, enable);
	}
	
	if(AWBset(cam, enable) == TRUE)
	{
		cam->cfg_ex.wbdisp = (boolean)enable;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_WBWget(mcxt dev, int32 *enable)
{
	cam_s		*cam = CAMMOD(dev);

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*enable = (int32)cam->cfg_ex.wbdisp;

	return	TRUE;
}

boolean cam_SHARPset(mcxt dev, int32 shp/*0~7*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_SHARPsetEMUL(dev, shp);
	}
	
	if(SHPset(cam, shp) == TRUE)
	{
		cam->cfg_ex.sharp = shp;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_SHARPget(mcxt dev, int32 *shp)
{
	cam_s		*cam = CAMMOD(dev);

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*shp = (int32)cam->cfg_ex.sharp;

	return	TRUE;
}

boolean cam_GAMset(mcxt dev, int32 mod/*0~3*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_GAMsetEMUL(dev, mod);
	}
	
	if(GAMset(cam, mod) == TRUE)
	{
		cam->cfg_ex.gamma = (byte)mod;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_GAMget(mcxt dev, int32 *mod)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*mod = (int32)cam->cfg_ex.gamma;
	
	return	TRUE;
}

boolean cam_BINset(mcxt dev, int32 val/*0~1024*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_BINsetEMUL(dev, val);
	}
	
	if(GBINset(cam, val) == TRUE)
	{
		cam->cfg_ex.bin = val;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_BINget(mcxt dev, int32 *val)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*val = (int32)cam->cfg_ex.bin;
	
	return	TRUE;
}

boolean cam_COLBARset(mcxt dev, int32 enable/*0~1*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_COLBARsetEMUL(dev, enable);
	}
	
	if(COLBset(cam, enable) == TRUE)
	{
		cam->cfg_ex.colbar = (boolean)enable;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_COLBARget(mcxt dev, int32 *enable)
{
	cam_s		*cam = CAMMOD(dev);

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*enable = (int32)cam->cfg_ex.colbar;

	return	TRUE;
}

boolean cam_BRTset(mcxt dev, int32 brt/*0~4*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_BRTsetEMUL(dev, brt);
	}
	
	if(BRTset(cam, brt) == TRUE)
	{
		cam->cfg_ex.brate = (byte)brt;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_BRTget(mcxt dev, int32 *brt)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*brt = (int32)cam->cfg_ex.brate;
	
	return	TRUE;
}

boolean cam_TRIGset(mcxt dev, int32 mod/*0~2*/)
{
	cam_s			*cam = CAMMOD(dev);

	if(ISEMUL(dev))
	{
		return	cam_TRIGsetEMUL(dev, mod);
	}
	
	if(TRGMset(cam, mod) == TRUE)
	{
		cam->cfg_ex.trigmod = (byte)mod;

		return	TRUE;
	}
	return	FALSE;
}

boolean cam_TRIGget(mcxt dev, int32 *mod)
{
	cam_s		*cam = CAMMOD(dev);
		
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	*mod = (int32)cam->cfg_ex.trigmod;
	
	return	TRUE;
}

/*=============================================================================
  DEVICE SYCHRONIZATION
=============================================================================*/
boolean SYNCex(cam_s *cam, CAM_CFGEX_s *s)
{
	CAM_CFGEX_s		*cfg;
	int32				val;
	
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	
	cfg = &cam->cfg_ex;

	if(s != NULL)
	{
		if(cfg->exp_time != s->exp_time)
		{
			if(SHTset(cam, s->exp_time)) cfg->exp_time = s->exp_time;
			else return	FALSE;
		}
		if(cfg->gain != s->gain)
		{
			if(GAINset(cam, s->gain)) cfg->gain = s->gain;
			else return	FALSE;
		}
		if(cfg->wbmod != s->wbmod)
		{
			if(WBset(cam, s->wbmod)) cfg->wbmod = s->wbmod;
			else return	FALSE;
		}
		if(cfg->wbdisp != s->wbdisp)
		{
			if(AWBset(cam, s->wbdisp)) cfg->wbdisp = s->wbdisp;
			else return	FALSE;
		}
		if(cfg->gamma != s->gamma)
		{
			if(GAMset(cam, s->gamma)) cfg->gamma = s->gamma;
			else return	FALSE;
		}
		if(cfg->bin != s->bin)
		{
			if(s->gamma == 3)
			{
				if(GBINset(cam, s->bin)) cfg->bin = s->bin;
				else return	FALSE;
			}
		}
		if(cfg->colbar != s->colbar)
		{
			if(strstr(cam->ver, "U1000C") != NULL)
			{
				if(COLBset(cam, s->colbar)) cfg->colbar = s->colbar;
				else return	FALSE;
			}
		}
		if(cfg->brate != s->brate)
		{
			if(BRTset(cam, s->brate)) cfg->brate = s->brate;
			else return	FALSE;
		}
		if(cfg->trigmod != s->trigmod)
		{
			if(TRGMset(cam, s->trigmod)) cfg->trigmod = s->trigmod;
			else return	FALSE;
		}
	
		return	TRUE;
	}
	
	if(SHTget(cam, &val)) cfg->exp_time = val;
	else return	FALSE;
	
	if(GAINget(cam, &val)) cfg->gain = val;
	else return	FALSE;

	if(WBget(cam, &val)) cfg->wbmod = (byte)val;
	else return	FALSE;

	if(AWBget(cam, &val)) cfg->wbdisp = (boolean)val;
	else return	FALSE;

	if(GAMget(cam, &val)) cfg->gamma = (byte)val;
	else return	FALSE;

	if(GBINget(cam, &val)) cfg->bin = val;
	else return	FALSE;

	if(COLBget(cam, &val)) cfg->colbar = (boolean)val;
	else return	FALSE;

	if(BRTget(cam, &val)) cfg->brate = (byte)val;
	else return	FALSE;

	if(TRGMget(cam, &val)) cfg->trigmod = (byte)val;
	else return	FALSE;
	
	return	TRUE;
} 

boolean GETex(cam_s *cam, CAM_CFGEX_s *s)
{
	CAM_CFGEX_s		*cfg;
	int32				val;
	
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}

	cfg = (CAM_CFGEX_s*)memCalloc(sizeof(*cfg));
	
	if(GAINget(cam, &val)) cfg->gain = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(SHTget(cam, &val)) cfg->exp_time = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(WBget(cam, &val)) cfg->wbmod = (byte)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(RGAINget(cam, &val)) cfg->rgain = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(BGAINget(cam, &val)) cfg->bgain = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(AWBget(cam, &val)) cfg->wbdisp = (boolean)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(SHPget(cam, &val)) cfg->sharp = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(GAMget(cam, &val)) cfg->gamma = (byte)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(GBINget(cam, &val)) cfg->bin = val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(COLBget(cam, &val)) cfg->colbar = (boolean)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(BRTget(cam, &val)) cfg->brate = (byte)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	if(TRGMget(cam, &val)) cfg->trigmod = (byte)val;
	else memFree(cfg);	cfg = NULL;	return	FALSE;

	memCopy(s, cfg, sizeof(*s));

	memFree(cfg);
	cfg = NULL;
	
	return	TRUE;
} 

/*=============================================================================
  INTERNAL COMMAND FUNCION DEFINITION
=============================================================================*/
//---------------------------------------------------------
// VERSION
//--------------------------------------------------------- 
boolean VERget(cam_s *cam)
{
	memZeros(cam->ver, sizeof(cam->ver));
	
	return	cam_MODEset(cam, "VERSION");
}

//---------------------------------------------------------
// GAIN CONTROL
//---------------------------------------------------------
boolean GAINset(mcxt dev, int32 gainTbl/*0~18*/) // 0 : gain auto adjustment
{
	return	cam_INT1set(CAMMOD(dev), "GAIN-STEP", gainTbl, 0, 18, 2);
}

boolean GAINget(mcxt dev, int32 *gainTbl)
{
	return	cam_INT1get(CAMMOD(dev), "GAIN_STEP", gainTbl);
}

//---------------------------------------------------------
// GAIN FINE-TUNES CONTROL
//---------------------------------------------------------
boolean GAINFset(mcxt dev, int32 gainfTbl/*0~522*/)
{
	return	cam_INT1set(CAMMOD(dev), "GAIN_FINE", gainfTbl, 0, 522, 3);
}

boolean GAINFget(mcxt dev, int32 *gainfTbl)
{
	return	cam_INT1get(CAMMOD(dev), "GAIN_FINE", gainfTbl);
}

//---------------------------------------------------------
// PEDESTAL SETTING
//---------------------------------------------------------
boolean PEDset(mcxt dev, int32 pedTbl/*0~255*/)
{
	return	cam_INT1set(CAMMOD(dev), "PEDESTAL", pedTbl, 0, 255, 3);
}

boolean PEDget(mcxt dev, int32 *pedTbl)
{
	return	cam_INT1get(CAMMOD(dev), "PEDESTAL", pedTbl);
}

//---------------------------------------------------------
// SHUTTER SPEED CONTROL
//---------------------------------------------------------
//	0 : OFF			5 : 1/250 s		10 : 1/10000s
//	1 : 1/15 s		6 : 1/500 s		11 : 1/7.5s
//	2 : 1/30 s		7 : 1/1000 s		12 : 1/2s
//	3 : 1/100 s		8 : 1/2000 s		13 : 1s
//	4 : 1/120 s		9 : 1/5000 s
boolean SHTset(mcxt dev, int32 shtTbl/*0~13*/)
{
	return	cam_INT1set(CAMMOD(dev), "SHUTTER", shtTbl, 0, 13, 2);
}

boolean SHTget(mcxt dev, int32 *shtTbl)
{
	return	cam_INT1get(CAMMOD(dev), "SHUTTER", shtTbl);
}

//---------------------------------------------------------
// TRIGGER MODE SETTING
//---------------------------------------------------------
//	0 : OFF			
//	1 : external trigger edge detected	
//	2 : external trigger pulse width detected
boolean TRGMset(mcxt dev, int32 trgTbl/*0~2*/)
{
	return	cam_INT1set(CAMMOD(dev), "TRG-MODE", trgTbl, 0, 2, 1);
}

boolean TRGMget(mcxt dev, int32 *trgTbl)
{
	return	cam_INT1get(CAMMOD(dev), "TRG-MODE", trgTbl);
}

//---------------------------------------------------------
// EXTERNAL TRIGGER POLARITY SETTING
//---------------------------------------------------------
//	0 : Negative
//	1 : Positive
boolean TRGPset(mcxt dev, int32 trgpTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "TRG-POL", trgpTbl, 0, 1, 1);
}

boolean TRGPget(mcxt dev, int32 *trgpTbl)
{
	return	cam_INT1get(CAMMOD(dev), "TRG-POL", trgpTbl);
}

//---------------------------------------------------------
// WHITE BALANCE MODE SETTING
//---------------------------------------------------------
//	0 : 3200K preset			2 : 6500K preset
//	1 : 5600K preset			3 : WB manual setting
//	4 : One Push AWB
boolean WBset(mcxt dev, int32 wbTbl/*0~4*/)
{
	return	cam_INT1set(CAMMOD(dev), "WBMODE", wbTbl, 0, 4, 1);
}

boolean WBget(mcxt dev, int32 *wbTbl)
{
	return	cam_INT1get(CAMMOD(dev), "WBMODE", wbTbl);
}

//---------------------------------------------------------
// MANUAL R GAIN SETTING (white balance mode 3 only)
//---------------------------------------------------------
boolean RGAINset(mcxt dev, int32 rgTbl/*0~0xFF*/)
{
	return	cam_INT1set(CAMMOD(dev), "RGAIN", rgTbl, 0, 128, 3);
}

boolean RGAINget(mcxt dev, int32 *rgTbl)
{
	return	cam_INT1get(CAMMOD(dev), "RGAIN", rgTbl);
}

//---------------------------------------------------------
// MANUAL B GAIN SETTING (white balance mode 3 only)
//---------------------------------------------------------
boolean BGAINset(mcxt dev, int32 bgTbl/*0~0xFF*/)
{
	return	cam_INT1set(CAMMOD(dev), "BGAIN", bgTbl, 0, 128, 3);
}

boolean BGAINget(mcxt dev, int32 *bgTbl)
{
	return	cam_INT1get(CAMMOD(dev), "BGAIN", bgTbl);
}

//---------------------------------------------------------
// AWB DETECTION RANGE DISPLAY
//---------------------------------------------------------
boolean AWBset(mcxt dev, int32 awbTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "AWBWINDOW", awbTbl, 0, 1, 1);
}

boolean AWBget(mcxt dev, int32 *awbTbl)
{
	return	cam_INT1get(CAMMOD(dev), "AWBWINDOW", awbTbl);
}

//---------------------------------------------------------
// SHARPNESS SETTING
//---------------------------------------------------------
boolean SHPset(mcxt dev, int32 shpTbl/*0~7*/)
{
	return	cam_INT1set(CAMMOD(dev), "SHARP", shpTbl, 0, 7, 1);
}

boolean SHPget(mcxt dev, int32 *shpTbl)
{
	return	cam_INT1get(CAMMOD(dev), "SHARP", shpTbl);
}

//---------------------------------------------------------
// DTL MODE SETTING (When set to OFF, automatically set "SHARP 0" & "DTL-SCL 0 0")
//---------------------------------------------------------
boolean DTLset(mcxt dev, int32 dtlTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "DTL-MODE", dtlTbl, 0, 1, 1);
}

boolean DTLget(mcxt dev, int32 *dtlTbl)
{
	return	cam_INT1get(CAMMOD(dev), "DTL-MODE", dtlTbl);
}

//---------------------------------------------------------
// GAMMA TABLE SETTING
//---------------------------------------------------------
//	0 : OFF			2 : Reverse
//	1 : ON			3 : Binarization
boolean GAMset(mcxt dev, int32 gamTbl/*0~3*/)
{
	return	cam_INT1set(CAMMOD(dev), "GAMMA", gamTbl, 0, 3, 1);
}

boolean GAMget(mcxt dev, int32 *gamTbl)
{
	return	cam_INT1get(CAMMOD(dev), "GAMMA", gamTbl);
}

//---------------------------------------------------------
// GAMMA BINARIZATION THRESHOLD SETTING (gamma table 3 only)
//---------------------------------------------------------
boolean GBINset(mcxt dev, int32 gbinTbl/*0~1024*/)
{
	return	cam_INT1set(CAMMOD(dev), "BINARIZE", gbinTbl, 0, 1024, 4);
}

boolean GBINget(mcxt dev, int32 *gbinTbl)
{
	return	cam_INT1get(CAMMOD(dev), "BINARIZE", gbinTbl);
}

//---------------------------------------------------------
// BINNING MODE SETTING (for XCL_U1000 only)
//---------------------------------------------------------
//	0 : OFF			1 : Vertical Binning
boolean  BINNset(mcxt dev, int32 binnTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "BINNING", binnTbl, 0, 1, 1);
}

boolean BINNget(mcxt dev, int32 *binnTbl)
{
	return	cam_INT1get(CAMMOD(dev), "BINNING", binnTbl);
}

//---------------------------------------------------------
// EXTERNAL TRIGGER SIGNAL INPUT SELECTION
//---------------------------------------------------------
//	0 : Camera Link		1 : DC
boolean EXTset(mcxt dev, int32 extTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "EXTTRG", extTbl, 0, 1, 1);
}

boolean EXTget(mcxt dev, int32 *extTbl)
{
	return	cam_INT1get(CAMMOD(dev), "EXTTRG", extTbl);
}

//---------------------------------------------------------
// COLOR BAR OUTPUT SETTING (for XCL-U1000C only)
//---------------------------------------------------------
//	0 : OFF			1 : ON
boolean COLBset(mcxt dev, int32 colTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "COLORBAR", colTbl, 0, 1, 1);
}

boolean COLBget(mcxt dev, int32 *colTbl)
{
	return	cam_INT1get(CAMMOD(dev), "COLORBAR", colTbl);
}

//---------------------------------------------------------
// GRAY SCALE OUPUT SETTING (for XCL-U1000 only)
//---------------------------------------------------------
//	0 : OFF			1 : ON
boolean GRYset(mcxt dev, int32 gryTbl/*0~1*/)
{
	return	cam_INT1set(CAMMOD(dev), "GRAYSCALE", gryTbl, 0, 1, 1);
}

boolean GRYget(mcxt dev, int32 *gryTbl)
{
	return	cam_INT1get(CAMMOD(dev), "GRAYSCALE", gryTbl);
}

//---------------------------------------------------------
// SERIAL COMMUNICATION SPEED SETTING
//---------------------------------------------------------
//	0 : 4800 [bps]			2 : 19200 [bps]
//	1 : 9600 [bps]			3 : 38400 [bps]
//	4 : 57600 [ bps]
boolean BRTset(mcxt dev, int32 brtTbl/*0~4*/)
{
	return	cam_INT1set(CAMMOD(dev), "BRATE", brtTbl, 0, 4, 1);
}

boolean BRTget(mcxt dev, int32 *brtTbl)
{
	return	cam_INT1get(CAMMOD(dev), "BRATE", brtTbl);
}

//---------------------------------------------------------
// PARTIAL SCAN SETTING
//---------------------------------------------------------
//	0 : OFF			1 : ON
boolean PARset(cam_s *cam, int32 mod/*0~1*/, int32 st/*0~15*/, int32 end/*1~16*/)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(mod, 0, 1))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(st, 0, 15))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(end, 1, 16))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "PARTIAL %d %d %d\r\n", mod, st, end);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean PARget(cam_s *cam, int32 *mod, int32 *st, int32 *end)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "PARTIAL\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*mod = tx->val.nval1;
		*st = tx->val.nval2;
		*end = tx->val.nval3;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// COLOR MATRIX SETTING (for XCL-U1000C only)
//---------------------------------------------------------
//	0 : OFF			2 : Data setting
//	1 : ON
boolean COLMset(cam_s *cam, int32 mod/*0~2*/, int32 ele/*0~8*/, int32 val/*0~0x3FF*/)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(mod, 0, 2))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(ele, 0, 8))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(val, 0, 1023))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "COLORMTX %d %d %d\r\n", mod, ele, val);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean COLMget(cam_s *cam, int32 *mod, int32 *ele, int32 *val)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "COLORMTX\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*mod = tx->val.nval1;
		*ele = tx->val.nval2;
		*val = tx->val.nval3;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// EDGE ENHANCEMENT FILTER COEFFICIENT SETTING
//---------------------------------------------------------
boolean DTLCset(cam_s *cam, int32 k0, int32 k1, int32 k2)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(k0, 0, 127))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(k1, 0, 127))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(k2, 0, 127))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-COEF %d %d %d\r\n", k0, k1, k2);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean DTLCget(cam_s *cam, int32 *k0, int32 *k1, int32 *k2)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	//Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-COEF\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*k0 = tx->val.nval1;
		*k1 = tx->val.nval2;
		*k2 = tx->val.nval3;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// EDGE ENHANCEMENT CORING THRESHOLD SETTING
//---------------------------------------------------------
boolean DTLTset(cam_s *cam, int32 nt, int32 pt)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(nt, 0, 255))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(pt, 0, 255))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-TH %d %d\r\n", nt, pt);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean DTLTget(cam_s *cam, int32 *nt, int32 *pt)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	//Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-TH\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*nt = tx->val.nval1;
		*pt = tx->val.nval2;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// EDGE ENHANCEMENT DATA SCALE SETTING
//---------------------------------------------------------
boolean DTLSset(cam_s *cam, int32 nt, int32 pt)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(nt, 0, 63))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(pt, 0, 63))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-SCL %d %d\r\n", nt, pt);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean DTLSget(cam_s *cam, int32 *nt, int32 *pt)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	//Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-SCL\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*nt = tx->val.nval1;
		*pt = tx->val.nval2;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// EDGE ENHANCEMENT DATA LEVEL SETTING
//---------------------------------------------------------
boolean DTLLset(cam_s *cam, int32 low, int32 upp)
{
	tx_s				*tx;
	boolean 			done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(low, 0, 1023))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}
	if(!RANGE_IN(upp, 0, 1023))
	{
		CAMERR_SET(cam, CAM_PARAM_EC);
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-LVL %d %d\r\n", low, upp);
	tx_type_set(tx, TX_REQ_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	tx_clear(tx);

	return	done;
}

boolean DTLLget(cam_s *cam, int32 *low, int32 *upp)
{
	tx_s			*tx;
	boolean 		done;

	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}

	//Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "DTL-LVL\r\n");
	tx_type_set(tx, TX_QUERY_T);

	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}

	done = tx->val.ack;
	if(done == TRUE)
	{
		*low = tx->val.nval1;
		*upp = tx->val.nval2;
	}
	tx_clear(tx);

	return	done;
}

//---------------------------------------------------------
// RETURN TO THE FACTORY DEFAULT 
//---------------------------------------------------------
boolean INITset(cam_s *cam)
{
	return	cam_MODEset(cam, "INIT");
}

//---------------------------------------------------------
// SETTING SAVE
//---------------------------------------------------------
boolean SAVset(cam_s *cam)
{
	return	cam_MODEset(cam, "SAVE");
}

//---------------------------------------------------------
// SETTING READ
//---------------------------------------------------------
boolean LOADset(cam_s *cam)
{
	return	cam_MODEset(cam, "LOAD");
}


/*=============================================================================
  BASIC COMM.
=============================================================================*/
boolean cam_MODEset(cam_s *cam, char *str)
{
	tx_s				*tx;
	boolean			done;
	

//	DBGPRINT("cam_modset\n");
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}
	
	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);
	
	sprintf(tx->ptr, "%s\r\n", str);
	tx_type_set(tx, TX_REQ_T);
	
	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}
	
	done = tx->val.ack;
	tx_clear(tx);
		
	return	done;
}

boolean cam_INT1set(cam_s *cam, char *str, int32 val, int32 min_val, int32 max_val, int32 digit)
{
	tx_s				*tx;
	boolean			done;
	int32			j, n;
	
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check range
	if(!RANGE_IN(val, min_val, max_val))
	{
		CAMERR_SET(cam, CAM_PARAM_EC); 
		return	FALSE;
	}

	tx = cam->tx;
	if(ISMASKON(tx->state, TX_SYNC_S))
	{
		CAMERR_SET(cam, CAM_IOPENDING_EC);
		return	FALSE;
	}
	
	// Make buffer & Command
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->tmp, "%s %", str);
	n = strlen(tx->tmp);
	if(digit > 0)
	{
		for(j=0; j<digit; j++, n++)
		{
			*(tx->tmp + n) = '0';
		}
		*(tx->tmp+n) = '0'+(char)digit; n++;
		*(tx->tmp+n) = 'd'; n++;
		*(tx->tmp+n) = '\r'; n++;
		*(tx->tmp+n) = '\n'; n++;
	}
	else
	{
		*(tx->tmp+n) = 'd'; n++;
		*(tx->tmp+n) = '\r'; n++;
		*(tx->tmp+n) = '\n'; n++;
	}
	
	sprintf(tx->ptr, tx->tmp, val);
	tx_type_set(tx, TX_REQ_T);
	
	if(scom_tx_req(cam) == FALSE)
	{
		return	FALSE;
	}
	
	done = tx->val.ack;
	tx_clear(tx);
		
	return	done;
}

boolean cam_INT1get(cam_s *cam, char *str, int32 *val)
{
	tx_s			*tx;
	boolean			done;
	
	if(cam == NULL)
		return	FALSE;

	if(cam->com == NULL)
	{
		CAMERR_SET(cam, CAM_INIT_EC);
		return	FALSE;
	}
	CAMERR_CLEAR(cam);

	// Check param
	if(val == NULL)
	{
		CAMERR_SET(cam, CAM_PARAM_EC); 
		return	FALSE;
	}
	
	// Make buffer & Command
	tx = cam->tx;
	tx_clear(tx);
	tx_clear_val(tx);

	sprintf(tx->ptr, "%s\r\n", str);
	tx_type_set(tx, TX_QUERY_T | TX_INT1_VAL);
	
	if(scom_tx_req(cam) == FALSE)
	{
		return	TRUE;
	}
	done = tx->val.ack;
	if(done)
	{
		*val = tx->val.nval1;
	}
	
	tx_clear(tx);
	
	return	tx->val.ack;
}

//---------------------------------------------------------
//   EVENT HANDLING
//---------------------------------------------------------
void cam_send_event(cam_s *cam, dword evt, dword wp, dword lp)
{
	if(cam->cli == NULL)
		return;

	if(cam->cli->EventCbf)
	{
		cam->cli->EventCbf(evt, wp, lp, cam->cli->pUserCxt);
	}
}

/*--- END OF hw_sony_cam.c ---*/

